package tt.dz.order.pojo;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import tt.dz.order.dao.BaseDAOUtil;
import tt.dz.order.util.OrderAppConfig;
import tt.dz.order.util.OrderConstant.AccountingStatus;

/**
 * @Title 订单系统发送台帐信息的状态
 * @author zhoutian   
 * @date 2015-11-26
 */
public class OrderAccountingStatus {
	private static Logger log = LoggerFactory.getLogger(OrderAccountingStatus.class);
	//订单号
	private String orderNo;
	//发送台帐信息的状态, 0：需要发送 1：正在发送 2：发送并接收回调完成
	private int accountingStatus;
	//发送失败次数
	private int failCount;
	//创建时间
	private Date createTime;
	
	public String getOrderNo() {
		return orderNo;
	}

	public void setOrderNo(String orderNo) {
		this.orderNo = orderNo;
	}

	public int getAccountingStatus() {
		return accountingStatus;
	}

	public void setAccountingStatus(int accountingStatus) {
		this.accountingStatus = accountingStatus;
	}

	public int getFailCount() {
		return failCount;
	}

	public void setFailCount(int failCount) {
		this.failCount = failCount;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public OrderAccountingStatus() {
		this.createTime = new Date();
		this.failCount = 0;
		this.accountingStatus = AccountingStatus.needSendNew.value();
	}
	
	private static final String select_all_sql = "select orderNo, accountingStatus, failCount, createTime from Order_Accounting_Status";
	
	private static final String insert_all_sql = "insert into Order_Accounting_Status(orderNo, accountingStatus, failCount, createTime) values(:orderNo, :accountingStatus, :failCount, :createTime)";
	
	public void save(){
		OrderInfo orderInfo=OrderInfo.getOrderInfoByOrderNo(this.orderNo);
		if(orderInfo!=null){
			if(OrderAppConfig.GET().getAccountingNotSendCardType().contains(","+orderInfo.getCardType()+",")){
				log.info("卡类型"+orderInfo.getCardType()+"不需要发送台账");
				return;
			}
			if(OrderAppConfig.GET().getAccountingNotSendAppId().contains(","+orderInfo.getAppId()+",")){
				log.info("渠道类型"+orderInfo.getAppId()+"不需要发送台账");
				return;
			}
		}
		BaseDAOUtil.updateObject(insert_all_sql, this);
	}

	/**
	 * 创建台帐pojo
	 * @param cuOrderNo 当前订单号
	 * @param isSerializable 是否持久到数据库之中 
	 * @return
	 */
	public static OrderAccountingStatus generatOrderAccountingStatus(String cuOrderNo,boolean isSerializable){
		// 生成订单发送台帐状态信息
		OrderAccountingStatus oas = new OrderAccountingStatus();
		oas.setOrderNo(cuOrderNo);
		if(isSerializable){
			oas.save();
		}
		return oas;
	}
	
	/**
	 * 批量生成待发送台帐信息
	 */
	@SuppressWarnings("unchecked")
	public static void batchSave(List<String> orderNos){
		Map<String, Object>[] batchValues = new HashMap[orderNos.size()];
		Date now = new Date();
		for(int i = 0 ; i < orderNos.size(); i++){
			String orderNo = orderNos.get(i);
			Map<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("orderNo", orderNo);
			paramMap.put("accountingStatus", AccountingStatus.needSendNew.value());
			paramMap.put("createTime", now);
			batchValues[i] = paramMap;
		}
		BaseDAOUtil.batchUpdate(insert_all_sql, batchValues);
	}
	
	/**
	 * 获取需要发送的订单列表（同时进行行锁）
	 * @return 订单列表
	 */
	public static List<OrderAccountingStatus> getAccountingInfoForSend(int failCount){
		String sql = select_all_sql + " where failCount < :failCount and (accountingStatus = " + AccountingStatus.needSendNew.value() + " or accountingStatus = " + AccountingStatus.needSendAgain.value() + ") ORDER BY createTime asc for update NOWAIT";
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("failCount", failCount);
		return BaseDAOUtil.queryForList(sql, paramMap, OrderAccountingStatus.class);
	}

	/**
	 * 查询达到失败次数限制的订单列表
	 * @return 订单列表
	 */
	public static List<OrderAccountingStatus> getAccountingByFailCount(int failCount){
		String sql = select_all_sql + " where failCount >= :failCount and accountingStatus = " + AccountingStatus.needSendAgain.value() + " ORDER BY createTime asc";
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("failCount", failCount);
		return BaseDAOUtil.queryForList(sql, paramMap, OrderAccountingStatus.class);
	}
	
	/**
	 * 修改订单台帐信息状态为"正在发送"
	 * @param orderNos 订单ID列表
	 */
	@SuppressWarnings("unchecked")
	public static void changeStatusToSending(List<String> orderNos){
		String sql = "update Order_Accounting_Status set accountingStatus = " + AccountingStatus.sending.value() + " where orderNo = :orderNo";
		Map<String, Object>[] batchValues = new HashMap[orderNos.size()];
		for(int i = 0 ; i < orderNos.size(); i++){
			String orderNo = orderNos.get(i);
			Map<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("orderNo", orderNo);
			batchValues[i] = paramMap;
		}
		BaseDAOUtil.batchUpdate(sql, batchValues);
	}
	
	/**
	 * 修改订单台帐信息状态为"需要再次发送"
	 * @param orderNos 订单ID列表
	 */
	@SuppressWarnings("unchecked")
	public static void changeStatusToNeedSendAgain(List<String> orderNos){
		String sql = "update Order_Accounting_Status set accountingStatus = " + AccountingStatus.needSendAgain.value() + ", failCount = failCount + 1 where orderNo = :orderNo";
		Map<String, Object>[] batchValues = new HashMap[orderNos.size()];
		for(int i = 0 ; i < orderNos.size(); i++){
			String orderNo = orderNos.get(i);
			Map<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("orderNo", orderNo);
			batchValues[i] = paramMap;
		}
		BaseDAOUtil.batchUpdate(sql, batchValues);
	}
	
	/**
	 * 修改订单台帐信息状态为"发送成功"
	 * @param orderNos 订单ID列表
	 */
	@SuppressWarnings("unchecked")
	public static void changeStatusToSuccess(List<String> orderNos){
		String sql = "update Order_Accounting_Status set accountingStatus = " + AccountingStatus.success.value() + " where orderNo = :orderNo";
		Map<String, Object>[] batchValues = new HashMap[orderNos.size()];
		for(int i = 0 ; i < orderNos.size(); i++){
			String orderNo = orderNos.get(i);
			Map<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("orderNo", orderNo);
			batchValues[i] = paramMap;
		}
		BaseDAOUtil.batchUpdate(sql, batchValues);
	}
	/**
	 * 根据订单号查询台账条数
	 * @param orderNo
	 * @return
	 */
	public static Long queryNumByOrderNo(String orderNo){
		String sql="select count(1) num from Order_Accounting_Status where orderno = :orderno";
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("orderno", orderNo);
		List<Map<String, Object>> list= BaseDAOUtil.queryForList(sql, paramMap);
		return (Long) list.get(0).get("num");
		
	}
}
